package tt.dz.egobus.servicemanager.business.key;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import tt.dz.egobus.api.managerservice.manager.RequestTask;
import tt.dz.egobus.bean.BaseBean;
import tt.dz.egobus.bean.BusinessStatus;
import tt.dz.egobus.servicemanager.bean.IdAlgorithm;
import tt.dz.egobus.servicemanager.business.point.BusPoint;
import tt.dz.egobus.servicemanager.core.builder.Builder;

import java.util.*;

/**
 * @author Anson
 * @date 17-3-27
 * @name 业务缓存id
 * @since 1.0.3
 */
public class BusinessCache implements BaseBean {
    private static final long serialVersionUID = 2093583757814951660L;

    //当前业务缓存一天时间
    public static final int BUSINESS_CACHE_EXPIRE = 24 * 60 * 60;

    /**
     * @param driverId 司机id
     * @author Anson
     * @date 17-3-27
     * @name 判断当前业务缓存集合是否存在司机的缓存
     * @since 1.0.3
     */
    public boolean isContain(String driverId) {
        if (this.drivers == null || this.drivers.length == 0) {
            return false;
        }
        BusPoint busPoint = this.get(driverId);
        return busPoint != null;
    }

    /**
     * @param driverId 司机id
     * @author Anson
     * @date 17-3-27
     * @name 获取当前业务缓存集合是否存在司机的缓存
     * 可能会返回空
     * @since 1.0.3
     */
    public BusPoint get(String driverId) {
        if (this.drivers == null || this.drivers.length == 0) {
            return null;
        }
        for (BusPoint busPoint : drivers) {
            if (busPoint.getDriverId().equals(driverId)) {
                return busPoint;
            }
        }
        return null;
    }

    /**
     * @param json BusinessCache 的字符串
     * @author Anson
     * @date 17-3-23
     * @name 将json字符串转换为bean
     * @since 1.0.2
     */
    public static BusinessCache toBean(String json) {
        return JSON.parseObject(json, BusinessCache.class);
    }

    /**
     * @author Anson
     * @date 17-8-9
     * @name 模块构建器
     * @since 1.0.6
     */
    public static BusinessCacheBuilder newBuilder() {
        return new BusinessCacheBuilder();
    }

    /**
     * @param businessId
     * @author Anson
     * @date 17-8-9
     * @name 缓存key生成器
     * @since 1.0.6
     */
    public static BusinessCacheKeyGenerator idGenerator(String businessId) {
        return new BusinessCacheKeyGenerator(businessId);
    }

    /**
     * @param cache 当前数据
     * @author Anson
     * @date 17-8-9
     * @name 模块构建器
     * @since 1.0.6
     */
    public static BusinessCacheBuilder newBuilder(BusinessCache cache) {
        return new BusinessCacheBuilder(cache);
    }

    /**
     * @author Anson
     * @date 17-3-23
     * @name 获取当前json值
     * @since 1.0.2
     */
    public String toJson() {
        return JSON.toJSONString(this);
    }


    /**
     * @author Anson
     * @date 17-3-28
     * @name 校验当前香瓜属性
     * @since 1.0.3
     */
    public boolean validate() {
        return !(StringUtils.isEmpty(userId) || StringUtils.isEmpty(businessId)
                || ArrayUtils.isEmpty(this.drivers) || this.requestTask == null);
    }

    /**
     * @author Anson
     * @date 17-8-10
     * @name 返回当前司机主键
     * @since 1.0.6
     */
    public List<String> convetDriverIds() {
        if (this.drivers == null || this.drivers.length == 0) {
            return Collections.emptyList();
        }
        List<String> ids = new ArrayList<>(this.drivers.length);
        for (BusPoint point : this.drivers) {
            ids.add(point.getDriverId());
        }
        return ids;
    }

    private RequestTask requestTask;


    private String userId;

    private String businessId;

    private BusPoint[] drivers;
    /**
     * 当前业务创建时间
     */
    private Long createDate = System.currentTimeMillis();

    private Date modifyDate;

    /**
     * 当前单的临时状态
     */
    private Integer status = BusinessStatus.ACTIVE.getCode();

    /**
     * 用户请求派单超时时间,单位秒
     */
    private Long limitTimeoutSeconds = 0L;

    /**
     * 当前司机抢单超时时间,单位秒
     */
    private Long grabLimitTimeoutSeconds = 0L;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
        this.systemCurrentModifyDate();
    }

    public String getBusinessId() {
        return businessId;
    }

    public void setBusinessId(String businessId) {
        this.businessId = businessId;
        this.systemCurrentModifyDate();
    }

    public BusPoint[] getDrivers() {
        return drivers;
    }

    public void setDrivers(BusPoint[] drivers) {
        this.drivers = drivers;
        this.systemCurrentModifyDate();
    }

    public Long getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Long createDate) {
        this.createDate = createDate;
    }

    public RequestTask getRequestTask() {
        return requestTask;
    }

    public void setRequestTask(RequestTask requestTask) {
        this.requestTask = requestTask;
        this.systemCurrentModifyDate();
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
        this.systemCurrentModifyDate();
    }

    public Long getLimitTimeoutSeconds() {
        return limitTimeoutSeconds;
    }

    public void setLimitTimeoutSeconds(Long limitTimeoutSeconds) {
        this.limitTimeoutSeconds = limitTimeoutSeconds;
        this.systemCurrentModifyDate();
    }

    public Long getGrabLimitTimeoutSeconds() {
        return grabLimitTimeoutSeconds;
    }

    public void setGrabLimitTimeoutSeconds(Long grabLimitTimeoutSeconds) {
        this.grabLimitTimeoutSeconds = grabLimitTimeoutSeconds;
        this.systemCurrentModifyDate();
    }

    public Date getModifyDate() {
        return modifyDate;
    }

    public void setModifyDate(Date modifyDate) {
        this.modifyDate = modifyDate;
    }

    public void systemCurrentModifyDate() {
        this.setModifyDate(new Date());
    }

    public void setStatus(BusinessStatus status) {
        this.setStatus(status.getCode());
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof BusinessCache)) return false;

        BusinessCache that = (BusinessCache) o;

        if (status != null ? !status.equals(that.status) : that.status != null) return false;
        if (getUserId() != null ? !getUserId().equals(that.getUserId()) : that.getUserId() != null) return false;
        return getBusinessId() != null ? getBusinessId().equals(that.getBusinessId()) : that.getBusinessId() == null;
    }

    @Override
    public int hashCode() {
        int result = status != null ? status.hashCode() : 0;
        result = 31 * result + (getUserId() != null ? getUserId().hashCode() : 0);
        result = 31 * result + (getBusinessId() != null ? getBusinessId().hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "BusinessCache{" +
                "requestTask=" + requestTask +
                ", status=" + status +
                ", userId='" + userId + '\'' +
                ", businessId='" + businessId + '\'' +
                ", limitTimeoutSeconds='" + limitTimeoutSeconds + '\'' +
                ", grabLimitTimeoutSeconds='" + grabLimitTimeoutSeconds + '\'' +
                ", drivers=" + Arrays.toString(drivers) +
                ", createDate=" + createDate +
                '}';
    }

    /**
     * @param
     * @author Anson
     * @date 17-8-9
     * @name
     * @since 1.0.6
     */
    public static class BusinessCacheKeyGenerator implements IdAlgorithm {

        private final String businessId;
        public static final String BUSINESS_CACHE_PRE = "EGOBUS_BUSINESS_";

        public BusinessCacheKeyGenerator(String businessId) {
            this.businessId = businessId;
        }

        @Override
        public String id() {
            return BUSINESS_CACHE_PRE + businessId;
        }
    }

    /**
     * @author Anson
     * @date 17-8-9
     * @name BusinessCache 构建器
     * @since 1.0.6
     */
    public static class BusinessCacheBuilder implements Builder<BusinessCache> {

        private final BusinessCache cache;

        BusinessCacheBuilder(BusinessCache cache) {
            this.cache = cache;
        }

        BusinessCacheBuilder() {
            this.cache = new BusinessCache();
        }


        public BusinessCacheBuilder setRequestTask(RequestTask requestTask) {
            this.cache.setRequestTask(requestTask);
            return this;
        }

        public BusinessCacheBuilder setStatus(Integer status) {
            this.cache.setStatus(status);
            return this;
        }

        public BusinessCacheBuilder setStatus(BusinessStatus status) {
            this.cache.setStatus(status);
            return this;
        }

        public BusinessCacheBuilder setUserId(String userId) {
            this.cache.setUserId(userId);
            return this;
        }

        public BusinessCacheBuilder setBusinessId(String businessId) {
            this.cache.setBusinessId(businessId);
            return this;
        }

        public BusinessCacheBuilder setDrivers(BusPoint[] drivers) {
            this.cache.setDrivers(drivers);
            return this;
        }

        public BusinessCacheBuilder setCreateDate(Long createDate) {
            this.cache.setCreateDate(createDate);
            return this;
        }

        public BusinessCacheBuilder setLimitTimeoutSeconds(Long limitTimeoutSeconds) {
            this.cache.setLimitTimeoutSeconds(limitTimeoutSeconds);
            return this;
        }

        public BusinessCacheBuilder setGrabLimitTimeoutSeconds(Long grabLimitTimeoutSeconds) {
            this.cache.setGrabLimitTimeoutSeconds(grabLimitTimeoutSeconds);
            return this;
        }

        @Override
        public BusinessCache builder() {
            return this.cache;
        }
    }
}
